package com.wisenet.service.sportwear;

import java.util.Date;
import java.util.SortedMap;
import java.util.TreeMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.wisenet.common.WxConst;
import com.wisenet.dao.sportwear.SportWearOrderDAO;
import com.wisenet.entity.SportWearOrder;
import com.wisenet.entity.WeixinPubno;
import com.wisenet.wx.tenpay.http.util.WeiXinPayUtil;
import com.wisenet.wx.tenpay.http.util.XMLUtil;
import com.wisenet.wx.util.SignUtil;

/**
 * 运动服商城支付服务类
 * @author fzh
 */
@Service
public class SportWearPayService {
	// 日志
	private static final Logger logger = LoggerFactory.getLogger(SportWearPayService.class);
	@Autowired
	private SportWearOrderDAO sportWearOrderDAO;

	/**
	 * 保存订单并发起支付
	 * @param orderParam
	 * @param type （save 或  update）
	 * @param weixinPubno
	 * @return
	 */
	public SortedMap<String, String> saveOrderAndPay(SportWearOrder orderParam, String type, WeixinPubno weixinPubno) {
		SortedMap<String, String> resultMap = null;
		
		logger.info("orderParam: " + JSONObject.toJSON(orderParam));
		
		String outTradeNo = SignUtil.getOrderNo();
		
		SortedMap<String, String> params = new TreeMap<String, String>();
		params.put("appid", weixinPubno.getAppid());
		params.put("mch_id", weixinPubno.getMchId());
		params.put("openid", orderParam.getUid());
		// 商户订单号
		params.put("out_trade_no", outTradeNo);
		params.put("body", orderParam.getTitle());
		params.put("nonce_str", SignUtil.getNonceStr(32));
		
		// 计算金额，单位为分
		Double totalPrice = WeiXinPayUtil.getMoney(orderParam.getPrice() * orderParam.getCount()) * 100;
		// 标价金额，单位为分
		params.put("total_fee", String.valueOf(totalPrice.intValue()));
		logger.info("total_fee = " + totalPrice/100 + " totalPrice = " + orderParam.getTotalPrice());
		
		params.put("trade_type", WxConst.TRADE_TYPE_JS);
		params.put("notify_url", weixinPubno.getNotifyUrl());
		params.put("spbill_create_ip", weixinPubno.getSpbillIp());
		
		// 创建MD5签名
		String sign = SignUtil.createSign(params, weixinPubno.getMchKey());
		params.put("sign", sign);
		logger.info("sign = " + sign);
		
		// 统一下单
		try {
			String xml = XMLUtil.getRequestXml(params);
			resultMap = WeiXinPayUtil.unifiedOrder(xml);
		} catch (Exception e) {
			logger.error(e.getMessage());
			resultMap = new TreeMap<String, String>();
			resultMap.put("errorMsg", e.getMessage());
			return resultMap;
		}
		
		// 处理返回结果
		if (resultMap == null) {
			resultMap = new TreeMap<String, String>();
			resultMap.put("errorMsg", "requestXml is null");
			return resultMap;
		}
		if ("FAIL".equals(resultMap.get("return_code"))) {
			resultMap = new TreeMap<String, String>();
			resultMap.put("errorMsg", resultMap.get("return_msg"));
			return resultMap;
		}
		if ("FAIL".equals(resultMap.get("result_code"))) {
			resultMap = new TreeMap<String, String>();
			resultMap.put("errorMsg", resultMap.get("err_code_des"));
			return resultMap;
		}
		
		String prepayId = resultMap.get("prepay_id");

		if ("".equals(prepayId)) {
			resultMap = new TreeMap<String, String>();
			resultMap.put("errorMsg", "prepay_id is empty");
			return resultMap;
		}
		
		// 保存订单记录
		try {
			orderParam.setPrepayId(prepayId);
			orderParam.setOutTradeNo(outTradeNo);
			orderParam.setCreateTime(new Date());
			if ("save".equals(type)) {
				saveOrder(orderParam);
			} else if ("update".equals(type)) {
				updateOrder(orderParam);
			}
			// 再次签名
			resultMap = WeiXinPayUtil.signAgain(prepayId, weixinPubno.getAppid(), weixinPubno.getMchKey());
			logger.info("signAgain: " + resultMap);
			return resultMap;
		} catch(Exception ex) {
			logger.info("db error: " + ex.getMessage());
			return null;
		}
	}

	private void saveOrder(SportWearOrder orderParam) {
		try {
			sportWearOrderDAO.insert(orderParam);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
	
	private void updateOrder(SportWearOrder orderParam) {
		try {
			sportWearOrderDAO.update(orderParam, "id");
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
}
